package com.codemes.happylist.modules.music;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.codemes.happylist.utils.CacheUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author nscoffee
 */
@Slf4j
@Data
public class MusicPlayList {

    private List<MusicFile> playList;

    private MusicFile curMusicFile;

    private Integer curMusicIndex;

    MusicPlayList(List<MusicFile> playList){
        this.playList = playList;
        if(CollUtil.isNotEmpty(playList)){
            CacheUtil.set(MUSIC_PLAY_LIST_CACHE_KEY, JSONUtil.toJsonStr(this));
        }else {
            String cache = CacheUtil.get(MUSIC_PLAY_LIST_CACHE_KEY);
            if(!ObjectUtils.isEmpty(cache)){
                log.info("init playList from cache -> {}",MUSIC_PLAY_LIST_CACHE_KEY);
                JSONObject cachePlayList = JSONUtil.parseObj(cache);
                this.setPlayList(cachePlayList.getJSONArray("playList").toList(MusicFile.class));
                this.setCurMusicFile(cachePlayList.get("curMusicFile",MusicFile.class));
                this.setCurMusicIndex(cachePlayList.getInt("curMusicIndex"));
            }
        }
    }

    /**
     * 列表循环
     * @return
     */
    public MusicFile listLoop(){
        return next();
    }

    /**
     * 上一首
     * @return
     */
    public MusicFile prev(){
        if(CollUtil.isEmpty(playList)){
            return null;
        }
        curMusicIndex=curMusicIndex==null?0:--curMusicIndex;
        curMusicIndex=curMusicIndex<0?0:curMusicIndex;
        curMusicFile = playList.get(curMusicIndex);
        return curMusicFile;
    }

    /**
     * 列表下一首
     * @return
     */
    public MusicFile next(){
        if(CollUtil.isEmpty(playList)){
            return null;
        }
        curMusicIndex=curMusicIndex==null?0:++curMusicIndex;
        if(curMusicIndex>=playList.size()){
            curMusicIndex = 0;
        }
        curMusicFile = playList.get(curMusicIndex);
        return curMusicFile;
    }

    /**
     * 随机
     * @return
     */
    public MusicFile random(){
        if(CollUtil.isEmpty(playList)){
            return null;
        }
        int size = playList.size();
        curMusicIndex = RandomUtil.randomInt(0,size);
        curMusicFile = playList.get(curMusicIndex);
        return curMusicFile;
    }

    /**
     * 单曲循环
     * @return
     */
    public MusicFile singleLoop(){
        return curMusicFile;
    }

    public MusicFile chooseMusicFile(MediaPlayerModel curModel) {
        switch (curModel){
            case MODEL_LOOP -> {
                return this.listLoop();
            }
            case MODEL_RANDOM -> {
                return this.random();
            }
            case MODEL_SINGLE -> {
                return this.singleLoop();
            }
            default -> {
                return this.curMusicFile;
            }
        }
    }

    public static final String MUSIC_PLAY_LIST_CACHE_KEY="MUSIC_PLAY_LIST_CACHE_KEY";
    public void newPlayList(List<MusicFile> musicFiles) {
        getPlayList().clear();
        getPlayList().addAll(musicFiles);
        CacheUtil.set(MUSIC_PLAY_LIST_CACHE_KEY, JSONUtil.toJsonStr(this));
    }
    public void add(MusicFile musicFile) {
        if(null==playList){
            playList = new ArrayList<>();
        }
        Optional<MusicFile> opt = playList.stream().filter(file -> {
            return file.getAbsPath().equals(musicFile.getAbsPath());
        }).findFirst();
        if(opt.isPresent()){
            return;
        }
        playList.add(musicFile);
        CacheUtil.set(MUSIC_PLAY_LIST_CACHE_KEY, JSONUtil.toJsonStr(this));
    }

    public void addAndPlay(MusicFile musicFile) {
        add(musicFile);
        this.curMusicFile=musicFile;
        this.curMusicIndex=playList.size()-1;
    }

    /**
     * 清空播放列表
     */
    public void clean(){
        this.getPlayList().clear();
    }
}
